#include "types.h"
#include "param.h"
#include "riscv.h"
#include "defs.h"
#include "proc.h"
#include "printf.h"

// 测试辅助函数：直接调用系统调用实现函数
extern int sys_getpid(void);
extern int sys_write(void);
extern int sys_read(void);
extern int sys_kill(void);
extern int sys_sbrk(void);
extern int sys_wait(void);
extern int sys_exit(void);

// 测试1：基础系统调用 - getpid
static void test_getpid(void) {
    printf("=== Test: sys_getpid ===\n");
    int pid = sys_getpid();
    printf("Current PID: %d\n", pid);
    if (pid > 0) {
        printf("getpid test: PASS\n");
    } else {
        printf("getpid test: FAIL\n");
    }
}

// 测试2：系统调用 - write
static void test_write(void) {
    printf("=== Test: sys_write ===\n");
    
    // 准备测试数据
    char test_msg[] = "Hello from sys_write test!\n";
    
    // 设置trapframe参数（模拟系统调用）
    struct proc *p = myproc();
    if (!p || !p->trapframe) {
        printf("test_write: no current process\n");
        return;
    }
    
    // 设置参数：fd=1, buf=test_msg, count=strlen(test_msg)
    p->trapframe->a0 = 1;  // fd = stdout
    p->trapframe->a1 = (uint64)test_msg;  // buf
    p->trapframe->a2 = 28;  // count
    
    int ret = sys_write();
    printf("write returned: %d\n", ret);
    if (ret == 28) {
        printf("write test: PASS\n");
    } else {
        printf("write test: FAIL (expected 28, got %d)\n", ret);
    }
}

// 测试3：系统调用 - sbrk
static void test_sbrk(void) {
    printf("=== Test: sys_sbrk ===\n");
    
    struct proc *p = myproc();
    if (!p || !p->trapframe) {
        printf("test_sbrk: no current process\n");
        return;
    }
    
    // 设置参数：n=1024
    p->trapframe->a0 = 1024;
    
    int ret = sys_sbrk();
    printf("sbrk(1024) returned: %d\n", ret);
    if (ret == 0) {
        printf("sbrk test: PASS\n");
    } else {
        printf("sbrk test: FAIL\n");
    }
}

// 测试4：系统调用 - kill（需要另一个进程）
static void test_kill(void) {
    printf("=== Test: sys_kill ===\n");
    
    struct proc *p = myproc();
    if (!p || !p->trapframe) {
        printf("test_kill: no current process\n");
        return;
    }
    
    // 尝试kill一个不存在的进程（应该返回-1）
    p->trapframe->a0 = 99999;  // 不存在的PID
    
    int ret = sys_kill();
    printf("kill(99999) returned: %d\n", ret);
    if (ret == -1) {
        printf("kill test (invalid PID): PASS\n");
    } else {
        printf("kill test: FAIL\n");
    }
}

// 测试5：系统调用 - wait
static void test_wait(void) {
    printf("=== Test: sys_wait ===\n");
    
    int ret = sys_wait();
    printf("wait() returned: %d\n", ret);
    // wait在没有子进程时应该返回-1
    if (ret == -1) {
        printf("wait test (no children): PASS\n");
    } else {
        printf("wait test: got PID %d\n", ret);
    }
}

// 测试入口函数
static void syscall_tests_entry(void) {
    printf("\n");
    printf("========================================\n");
    printf("System Call Tests Starting\n");
    printf("========================================\n");
    printf("\n");
    
    test_getpid();
    printf("\n");
    
    test_write();
    printf("\n");
    
    test_sbrk();
    printf("\n");
    
    test_kill();
    printf("\n");
    
    test_wait();
    printf("\n");
    
    printf("========================================\n");
    printf("System Call Tests Complete\n");
    printf("========================================\n");
    
    // 测试完成后退出
    exit_process(0);
}

// 对外暴露：由 main 调用
void syscall_tests_start(void) {
    int pid = create_process(syscall_tests_entry);
    if (pid < 0) {
        printf("syscall_tests_start: create process failed\n");
    } else {
        printf("syscall_tests_start: created test process (PID=%d)\n", pid);
    }
}